<template>
  <el-form
    ref="formLabels"
    :model="formData"
    :rules="rules"
    :dict-list="dictList"
    class="demo-formLabels"
    :label-width="labelWidth + 'px'"
    v-bind="$attrs"
    :label-position="labelPosition"
    :disabled="isDisabled"
    @submit.native.prevent
  >
    <el-row class="flex el-row-flex">
      <template v-for="(item, index) in formLabels">
        <el-col
          v-if="!item.hidden"
          :key="index"
          :span="item.span ? item.span : 12"
        >
          <!--   文本框   -->
          <el-form-item
            :label-width="
              item.labelWidth ? item.labelWidth + 'px' : labelWidth + 'px'
            "
            :label="item.label"
            :prop="item.field"
          >
            <span v-if="item.showPrefix" class="el-input__prefix">C</span>
            <el-input
              v-if="item.type == 'input'"
              v-model="formData[item.field]"
              :clearable="true"
              :place-holder="getPlaceHolder(item)"
              v-bind="item.attrs"
              :maxlength="item.maxlength"
              :disabled="item.disabled"
              @blur="handleEvent($event, item.field)"
            />
            <!--   密码框   -->
            <el-input
              v-if="item.type == 'password'"
              v-model="formData[item.field]"
              :clearable="true"
              show-password
              :place-holder="getPlaceHolder(item)"
              :disabled="item.disabled"
              v-bind="item.attrs"
              @change="handleEvent($event, item.field, 'change')"
            />
            <!--   下拉框   -->
            <el-select
              v-if="item.type == 'select'"
              v-model="formData[item.field]"
              :clearable="true"
              :placeholder="getPlaceHolder(item)"
              :disabled="item.disabled"
              v-bind="item.attrs"
              style="width: 100%"
              @change="handleEvent($event, item.field, 'change')"
            >
              <el-option
                v-for="(el, i) in dictList[item.list]"
                :key="i"
                :label="el.label"
                :value="el.value"
                :disabled="el.disabled"
              />
            </el-select>
            <!--   级联选择器   -->
            <el-cascader
              v-if="item.type == 'cascader'"
              v-model="formData[item.field]"
              v-bind="item.attrs"
              :options="dictList[item.list]"
              :clearable="true"
              :props="item.props"
              style="width: 100%"
              @change="handleEvent($event, item.field, 'change')"
            />
            <!--   开关   -->
            <el-switch
              v-if="item.type == 'switch'"
              v-model="formData[item.field]"
              :disabled="item.disabled"
              v-bind="item.attrs"
              @change="handleEvent($event, item.field, 'change')"
            />
            <!--   复选框   -->
            <el-checkbox-group
              v-if="item.type == 'checkbox'"
              v-model="formData[item.field]"
              style="width: 100%"
              @change="handleEvent($event, item.field, 'change')"
            >
              <el-checkbox
                v-for="el in dictList[item.list]"
                :key="el.value"
                :label="el.label"
                :disabled="item.disabled"
                v-bind="item.attrs"
              >{{ el.label }}
              </el-checkbox>
            </el-checkbox-group>
            <!--   单选框   -->
            <el-radio-group
              v-if="item.type == 'radio'"
              v-model="formData[item.field]"
              v-bind="item.attrs"
              style="width: 100%"
              @change="handleEvent($event, item.field, 'change')"
            >
              <el-radio
                v-for="el in dictList[item.list]"
                :key="el.value"
                :label="el.value"
                :disabled="item.disabled"
                v-bind="item.attrs"
                style="margin-bottom: 5px"
              >
                {{ el.label }}
              </el-radio>
            </el-radio-group>
            <!--   文本域   -->
            <el-input
              v-if="item.type == 'textarea'"
              v-model="formData[item.field]"
              type="textarea"
              :clearable="true"
              style="width: 100%"
              :place-holder="getPlaceHolder(item)"
              :maxlength="item.maxlength"
              v-bind="item.attrs"
              @blur="handleEvent($event, item.field)"
            />
            <!--   计数器   -->
            <el-input-number
              v-if="item.type == 'number'"
              v-model="formData[item.field]"
              style="width: 100%"
              controls-position="right"
              v-bind="item.attrs"
              @change="handleEvent($event, item.field, 'change')"
            />
            <!--   日期时间选择器   -->
            <el-date-picker
              v-if="item.type == 'dateTime'"
              v-model="formData[item.field]"
              size="mini"
              style="width: 100%"
              type="datetime"
              :value-format="item.format"
              placeholder="选择日期时间"
              @change="handleEvent($event, item.field, 'change')"
            />
            <!--    日期选择器    -->
            <el-date-picker
              v-if="item.type == 'datePicker'"
              v-model="formData[item.field]"
              style="width: 100%"
              type="date"
              placeholder="选择日期"
              :value-format="item.format"
              @change="handleEvent($event, item.field, 'change')"
            />
            <!--    日期区间选择器    -->
            <el-date-picker
              v-if="item.type == 'dateRange'"
              v-model="formData[item.field]"
              style="width: 100%"
              type="daterange"
              range-separator="至"
              start-placeholder="开始日期"
              end-placeholder="结束日期"
              @change="handleEvent($event, item.field, 'change')"
            />
            <!--    插槽    -->
            <slot v-if="item.type == 'slot'" :name="'filter-' + item.field" />
          </el-form-item>
        </el-col>
      </template>
    </el-row>
    <el-form-item style="flex: 1; display: flex; justify-content: end">
      <slot />
    </el-form-item>
    <div v-show="!btnHidden" style="width: 100%; text-align: right">
      <el-button
        type="primary"
        @click="handleFormSubmit('formLabels')"
      >保 存</el-button>
      <el-button @click="resetForm('formLabels')">取消</el-button>
    </div>
  </el-form>
</template>

<script>
export default {
  props: {
    labelPosition: {
      type: String,
      default: 'right'
    },
    data: {
      type: Object,
      default() {
        return {}
      }
    },
    isDisabled: {
      type: Boolean,
      default() {
        return false
      }
    },
    formLabels: {
      type: Array,
      default() {
        return []
      }
    },
    fieldList: {
      type: Array,
      default() {
        return []
      }
    },
    rules: {
      type: Object,
      default() {
        return {}
      }
    },
    dictList: {
      type: Object,
      default() {
        return {}
      }
    },
    labelWidth: {
      type: String,
      default() {
        return '100'
      }
    },
    btnHidden: {
      type: Boolean,
      default() {
        return false
      }
    }
  },
  data() {
    return {
      // defaultData: this.data,
      // formData: this.data,
      defaultKeyList: []
    }
  },
  computed: {
    formData() {
      return this.data
    },
    defaultData() {
      return this.data
    }
  },
  watch: {
    // data: {
    //   handler(newVal) {
    //     console.log(newVal);
    //     this.formData= Object.assign(this.formData, newVal)

    //   },
    //   deep: true,
    //   immediate: true
    // },
    data: {
      handler(newVal) {},
      deep: true,
      immediate: true
    }
  },
  methods: {
    /**
     *定义占位符
     * @param item
     */

    getPlaceHolder(item) {
      let placeHolder = ''
      if (
        item.type === 'input' ||
        item.type === 'number' ||
        item.type === 'textarea'
      ) {
        placeHolder = `请输入${item.label}`
      } else if (item.type === 'select' || item.type === 'cascader') {
        if (item?.attrs?.placeholder) {
          placeHolder = `${item.attrs.placeholder}`
        } else {
          placeHolder = `请选择${item.label}`
        }
      } else if (item.type === 'date') {
        placeHolder = `请选择${item.label}`
      }
      return placeHolder
    },
    /**
     * 提交 校验
     * @returns {Promise<unknown>}
     */
    handleFormSubmit(formName) {
      const _self = this
      return new Promise((resolve) => {
        _self.$refs[formName]
          .validate()
          .then(() => {
            resolve(_self.formData)
            this.$emit('handleSubmitEvent', _self.formData)
          })
          .catch(() => {
            _self.$message({
              message: '请完善表单！',
              type: 'error'
            })
          })
      })
    },
    /**
     * 取消
     * */
    resetForm(formName) {
      this.$refs[formName].resetFields()
      this.$emit('handleCancel')
    },
    /**
     * @func 事件处理
     * @desc 📝
     */
    handleEvent(event, val, change) {
      this.defaultKeyList.indexOf(val) < 0 && this.defaultKeyList.push(val)
      const obj = {
        value: change === 'change' ? event : event.target.value,
        field: val
      }
      this.$forceUpdate()
      this.$emit('handleEvent', obj)
    }
  }
}
</script>
<style lang="scss" scoped>
.el-form-item {
  margin: 10px;
}

.el-form {
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
}
.el-input__prefix {
  z-index: 100;
}
.el-row-flex {
  width: 100%;
  flex-wrap: wrap;
}
::v-deep .el-cascader {
  width: 100% !important;
}
</style>
